home *** CD-ROM | disk | FTP | other *** search
/ Aminet 6 / Aminet 6 - June 1995.iso / Aminet / text / hyper / ADtoHT2_0.lha / Includes.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-03-19  |  21.8 KB  |  824 lines

  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <stdlib.h>
  4.  
  5. /************************************************************************/
  6.  
  7. #include "main.h"
  8. #include "File.h"
  9. #include "ProcessDir.h"
  10. #include "Includes.h"
  11. #include "Autodocs.h"
  12. #include "FormatNode.h"
  13. #include "AdditionalDocs.h"
  14.  
  15. /************************************************************************/
  16.  
  17. struct AVLTree IncludeFileTree =
  18. {NULL, (int (*)(struct AVLNode *, struct AVLNode *)) nodecasecmp};
  19. struct AVLTree StructureTree =
  20. {NULL, (int (*)(struct AVLNode *, struct AVLNode *)) nodecmp};
  21. struct AVLTree UnionTree =
  22. {NULL, (int (*)(struct AVLNode *, struct AVLNode *)) nodecmp};
  23. struct AVLTree TypedefTree =
  24. {NULL, (int (*)(struct AVLNode *, struct AVLNode *)) nodecmp};
  25. struct AVLTree DefinesTree =
  26. {NULL, (int (*)(struct AVLNode *, struct AVLNode *)) nodecmp};
  27.  
  28. /************************************************************************/
  29. /*                                                                      */
  30. /* Create a new IncludeItemNodeNode                                     */
  31. /*                                                                      */
  32. /************************************************************************/
  33.  
  34. static struct IncludeItemNodeNode *
  35. CreateIncludeItem (char *Name,
  36.            struct AVLTree *Tree,
  37.            struct IncludeFileNode *IncludeFileNode,
  38.            ULONG Line)
  39.  
  40. {
  41.   struct IncludeItemNode *IncludeItemNode;
  42.   struct IncludeItemNodeNode *IncludeItemNodeNode;
  43.   struct IncludeItemNodeNode **Current;
  44.  
  45.   if (!(IncludeItemNode = (struct IncludeItemNode *) SearchNode (Tree, Name)))
  46.     {
  47.       IncludeItemNode = (struct IncludeItemNode *) CreateNode (Name, sizeof (*IncludeItemNode));
  48.       IncludeItemNode->Entries = NULL;
  49.       IncludeItemNode->Function = FALSE;
  50.       AVL_InsertNode (Tree, &IncludeItemNode->AnyNode.AVLNode);
  51.     }
  52.   IncludeItemNodeNode = xmalloc (sizeof (*IncludeItemNodeNode));
  53.   IncludeItemNodeNode->IncludeFileNode = IncludeFileNode;
  54.   IncludeItemNodeNode->IncludeItemNode = IncludeItemNode;
  55.   IncludeItemNodeNode->Line = Line;
  56.  
  57.   Current = &(IncludeItemNode->Entries);
  58.   while (*Current)
  59.     {
  60.       int Result;
  61.  
  62.       Result = strcasecmp ((*Current)->IncludeFileNode->AnyNode.Name,
  63.             IncludeItemNodeNode->IncludeFileNode->AnyNode.Name);
  64.       if (Result > 0)
  65.     {
  66.       break;
  67.     }
  68.       if (Result == 0)
  69.     {
  70.       if ((*Current)->Line > IncludeItemNodeNode->Line)
  71.         {
  72.           break;
  73.         }
  74.     }
  75.       Current = &((*Current)->Next);
  76.     }
  77.   IncludeItemNodeNode->Next = *Current;
  78.   *Current = IncludeItemNodeNode;
  79.  
  80.   return IncludeItemNodeNode;
  81. }
  82.  
  83. /************************************************************************/
  84. /*                                                                      */
  85. /* Write a word, creating links to #defines and typedefs                */
  86. /*                                                                      */
  87. /************************************************************************/
  88.  
  89. void
  90. WriteIdentifier (struct Word *Word, struct IncludeFileNode *CurrentIncludeFile)
  91.  
  92. {
  93.   if (Pass2)
  94.     {
  95.       if (Word->Length > 1)
  96.     {
  97.       struct IncludeItemNode *IncludeItemNode;
  98.  
  99.       WriteWhitespace (Word);
  100.  
  101.       if ((IncludeItemNode = (struct IncludeItemNode *) SearchNode (&DefinesTree, Word->Word)) ||
  102.           (IncludeItemNode = (struct IncludeItemNode *) SearchNode (&TypedefTree, Word->Word)))
  103.         {
  104.           struct IncludeItemNodeNode *IncludeItemNodeNode;
  105.  
  106.           IncludeItemNodeNode = IncludeItemNode->Entries;
  107.           while (IncludeItemNodeNode && IncludeItemNodeNode->IncludeFileNode!=CurrentIncludeFile)
  108.         {
  109.           IncludeItemNodeNode=IncludeItemNodeNode->Next;
  110.         }
  111.           if (IncludeItemNodeNode)
  112.         {
  113.           WPrintf ("@{\x22%s\x22 LINK File %lu}",
  114.                Word->Word, IncludeItemNodeNode->Line);
  115.         }
  116.           else
  117.         {
  118.           IncludeItemNodeNode=IncludeItemNode->Entries;
  119.           WPrintf ("@{\x22%s\x22 LINK \x22%s/File\x22 %lu}",
  120.                Word->Word,
  121.                IncludeItemNodeNode->IncludeFileNode->LinkName,
  122.                IncludeItemNodeNode->Line);
  123.         }
  124.           return;
  125.         }
  126.     }
  127.       WriteWord (Word);
  128.     }
  129. }
  130.  
  131. /************************************************************************/
  132. /*                                                                      */
  133. /* Read a C token, handling comments                                    */
  134. /*                                                                      */
  135. /************************************************************************/
  136.  
  137. static struct Word *ReadToken (int AllowEOF, struct IncludeFileNode *CurrentIncludeFile)
  138.  
  139. {
  140.   struct Word *Word;
  141.  
  142.   do
  143.     {
  144.       Word = ReadWord (AllowEOF);
  145.       if (Word->Word[0] == '/')
  146.     {
  147.       struct Word *NextWord;
  148.  
  149.       NextWord = ReadWord (FALSE);
  150.       if (!NextWord->Whitespace && !NextWord->Newline && NextWord->Word[0] == '*')
  151.         {
  152.           /* found a comment */
  153.           WriteWord (Word);
  154.           FreeWord (Word);
  155.           WriteWord (NextWord);
  156.           FreeWord (NextWord);
  157.           ConvertNodeText (TRUE, CurrentIncludeFile);
  158.           Word = NULL;
  159.         }
  160.       else
  161.         {
  162.           UnreadWord (NextWord);
  163.         }
  164.     }
  165.     }
  166.   while (!Word);
  167.   return Word;
  168. }
  169.  
  170. /************************************************************************/
  171. /*                                                                      */
  172. /* Look for the "current" node in a tree.                */
  173. /* If that node is found, write it (creating a link if necessary).    */
  174. /* If that node is not found, return NULL and don't write anything.    */
  175. /*                                                                      */
  176. /************************************************************************/
  177.  
  178. static struct IncludeItemNodeNode *DoCurrentItem(struct IncludeFileNode *CurrentIncludeFile,
  179.                          ULONG CurrentLine,
  180.                          struct Word *Word,
  181.                          struct AVLTree *Tree,
  182.                          int CheckAutodocs)
  183.  
  184. {
  185.   struct IncludeItemNode *IncludeItemNode;
  186.  
  187.   if ((IncludeItemNode=(struct IncludeItemNode *)SearchNode(Tree,Word->Word)))
  188.     {
  189.       struct IncludeItemNodeNode *IncludeItemNodeNode;
  190.  
  191.       for (IncludeItemNodeNode=IncludeItemNode->Entries;
  192.        (IncludeItemNodeNode &&
  193.         (IncludeItemNodeNode->IncludeFileNode!=CurrentIncludeFile || IncludeItemNodeNode->Line!=CurrentLine));
  194.        IncludeItemNodeNode=IncludeItemNodeNode->Next)
  195.     ;
  196.       if (IncludeItemNodeNode)
  197.     {
  198.       struct IncludeItemNodeNode *LinkDestNode;
  199.  
  200.       if ((LinkDestNode=IncludeItemNodeNode->Next))
  201.         {
  202.         DoIncludeLink:
  203.           WriteWhitespace(Word);
  204.           WPrintf ("@{\x22");
  205.           WriteWord (Word);
  206.           WPrintf ("\x22 LINK \x22");
  207.           if (LinkDestNode->IncludeFileNode != CurrentIncludeFile)
  208.         {
  209.           WPrintf ("%s/", LinkDestNode->IncludeFileNode->LinkName);
  210.         }
  211.           WPrintf ("File\x22 %lu}", LinkDestNode->Line);
  212.         }
  213.       else
  214.         {
  215.           if (!CheckAutodocs || !DoAutodoc (Word, NULL))
  216.         {
  217.           LinkDestNode=IncludeItemNode->Entries;
  218.           if (LinkDestNode->Next)
  219.             {
  220.               goto DoIncludeLink;
  221.             }
  222.           WriteWord (Word);
  223.         }
  224.         }
  225.     }
  226.       return IncludeItemNodeNode;
  227.     }
  228.   return NULL;
  229. }
  230.  
  231. /************************************************************************/
  232. /*                                                                      */
  233. /* Handle struct/union stuff                                            */
  234. /* This function is expected to read the struct/union as first word     */
  235. /* Returns the name of the variable (i.e. the last name before the ';'  */
  236. /*                                                                      */
  237. /************************************************************************/
  238.  
  239. static struct Word *
  240. StructUnion (struct IncludeFileNode *CurrentIncludeFile)
  241.  
  242. {
  243.   static unsigned int BlockDepth;
  244.   static struct IncludeItemNodeNode *CurrentStructure;
  245.  
  246.   struct Word *StartWord;
  247.   struct Word *IdentifierWord;
  248.   struct Word *Word;
  249.   struct Word *VariableWord;
  250.  
  251.   if (!BlockDepth)
  252.     {
  253.       CurrentStructure = NULL;
  254.     }
  255.   BlockDepth++;
  256.  
  257.   VariableWord = NULL;
  258.   StartWord = ReadWord (FALSE);
  259.   WriteWhitespace (StartWord);
  260.  
  261.   IdentifierWord = ReadToken (FALSE, CurrentIncludeFile);
  262.   if (IdentifierWord->Word[0] != '{')
  263.     {
  264.       /* named struct/union */
  265.       /* struct Identifier ... */
  266.  
  267.       Word = ReadToken (FALSE, CurrentIncludeFile);
  268.       if (Word->Word[0] != '{')
  269.     {
  270.       /* struct/union usage */
  271.       /* struct Identifier Object */
  272.  
  273.       if (Pass2)
  274.         {
  275.           struct IncludeItemNode *IncludeItemNode;
  276.  
  277.           if ((IncludeItemNode = (struct IncludeItemNode *)
  278.            SearchNode (StartWord->Word[0] == 'u' ?
  279.                    &UnionTree : &StructureTree,
  280.                    IdentifierWord->Word)))
  281.         {
  282.           struct IncludeItemNodeNode *IncludeItemNodeNode;
  283.  
  284.           for (IncludeItemNodeNode = IncludeItemNode->Entries;
  285.                IncludeItemNodeNode && IncludeItemNodeNode!=CurrentStructure;
  286.                IncludeItemNodeNode=IncludeItemNodeNode->Next)
  287.             ;
  288.           if (!IncludeItemNodeNode)
  289.             {
  290.               for (IncludeItemNodeNode=IncludeItemNode->Entries;
  291.                IncludeItemNodeNode && IncludeItemNodeNode->IncludeFileNode!=CurrentIncludeFile;
  292.                IncludeItemNodeNode=IncludeItemNodeNode->Next)
  293.             ;
  294.               if (!IncludeItemNodeNode)
  295.             {
  296.               IncludeItemNodeNode=IncludeItemNode->Entries;
  297.             }
  298.               if (!IdentifierWord->Newline)
  299.             {
  300.               WPrintf ("@{\x22");
  301.               WriteWord (StartWord);
  302.             }
  303.               else
  304.             {
  305.               WriteWord (StartWord);
  306.               WPrintf ("@{\x22");
  307.             }
  308.               WriteWord (IdentifierWord);
  309.               if (CurrentIncludeFile == IncludeItemNodeNode->IncludeFileNode)
  310.             {
  311.               WPrintf ("\x22 LINK File %lu}", IncludeItemNodeNode->Line);
  312.             }
  313.               else
  314.             {
  315.               WPrintf ("\x22 LINK \x22%s/File\x22 %lu}",
  316.                    IncludeItemNodeNode->IncludeFileNode->LinkName,
  317.                    IncludeItemNodeNode->Line);
  318.             }
  319.             }
  320.           else
  321.             {
  322.               WriteWord (StartWord);
  323.               WriteWord (IdentifierWord);
  324.             }
  325.         }
  326.           else
  327.         {
  328.           WriteWord (StartWord);
  329.           WriteWord (IdentifierWord);
  330.         }
  331.         }
  332.       do
  333.         {
  334.           WriteWord (Word);
  335.           if (Word->Length > 1 || !Word->Special)
  336.         {
  337.           FreeWord (VariableWord);
  338.           VariableWord = Word;
  339.         }
  340.           else
  341.         {
  342.           FreeWord (Word);
  343.         }
  344.           Word = ReadToken (FALSE, CurrentIncludeFile);
  345.         }
  346.       while (Word->Word[0] != ';' && Word->Word[0] != ')');
  347.       UnreadWord (Word);
  348.       FreeWord (IdentifierWord);
  349.       FreeWord (StartWord);
  350.       BlockDepth--;
  351.       return VariableWord;
  352.     }
  353.       else
  354.     {
  355.       /* struct/union definition */
  356.       /* struct Identifier {...} */
  357.  
  358.       WriteWord (StartWord);
  359.       if (!Pass2)
  360.         {
  361.           if (BlockDepth == 1)
  362.         {
  363.           CurrentStructure=CreateIncludeItem (IdentifierWord->Word,
  364.                               StartWord->Word[0] == 'u' ? &UnionTree : &StructureTree,
  365.                               CurrentIncludeFile,
  366.                               StartWord->Line);
  367.         }
  368.         }
  369.       else
  370.         {
  371.           if (BlockDepth==1)
  372.         {
  373.           CurrentStructure=DoCurrentItem(CurrentIncludeFile,
  374.                          StartWord->Line,
  375.                          IdentifierWord, 
  376.                          StartWord->Word[0] == 'u' ? &UnionTree : &StructureTree,
  377.                          FALSE);
  378.         }
  379.           else
  380.         {
  381.           WriteWord (IdentifierWord);
  382.         }
  383.         }
  384.     }
  385.       WriteWord (Word);
  386.       FreeWord (Word);
  387.     }
  388.   else
  389.     {
  390.       WriteWord (StartWord);
  391.     }
  392.   FreeWord (StartWord);
  393.   FreeWord (IdentifierWord);
  394.  
  395.   /* Take care of the structure body */
  396.   /* {...}; */
  397.  
  398.   Word = ReadToken (FALSE, CurrentIncludeFile);
  399.   while (Word)
  400.     {
  401.       if (Word->Word[0] == '}')
  402.     {
  403.       WriteWord (Word);
  404.       FreeWord (Word);
  405.       Word = NULL;
  406.     }
  407.       else if (!strcmp (Word->Word, "struct") ||
  408.            !strcmp (Word->Word, "union"))
  409.     {
  410.       UnreadWord (Word);
  411.       FreeWord (StructUnion (CurrentIncludeFile));
  412.       Word = ReadToken (FALSE, CurrentIncludeFile);
  413.     }
  414.       else
  415.     {
  416.       WriteIdentifier (Word, CurrentIncludeFile);
  417.       if (Word->Length > 1 || !Word->Special)
  418.         {
  419.           FreeWord (VariableWord);
  420.           VariableWord = Word;
  421.         }
  422.       else
  423.         {
  424.           FreeWord (Word);
  425.         }
  426.       Word = ReadToken (FALSE, CurrentIncludeFile);
  427.     }
  428.     }
  429.   Word = ReadToken (FALSE, CurrentIncludeFile);
  430.   while (Word->Word[0] != ';')
  431.     {
  432.       WriteWord (Word);
  433.       if (Word->Length > 1 || !Word->Special)
  434.     {
  435.       FreeWord (VariableWord);
  436.       VariableWord = Word;
  437.     }
  438.       else
  439.     {
  440.       FreeWord (Word);
  441.     }
  442.       Word = ReadToken (FALSE, CurrentIncludeFile);
  443.     }
  444.   UnreadWord (Word);
  445.   BlockDepth--;
  446.   return VariableWord;
  447. }
  448.  
  449. /************************************************************************/
  450. /*                                                                      */
  451. /* Functions to be called from FormatNode()/PrintLink()            */
  452. /*                                                                      */
  453. /************************************************************************/
  454.  
  455. struct FormatParameters
  456. {
  457.   struct IncludeFileNode *IncludeFileNode;
  458.   struct AVLTree *Tree;
  459.  
  460.   struct AVLStateInfo StateInfo;
  461.   struct IncludeItemNodeNode *IncludeItemNodeNode;
  462. };
  463.  
  464. /************************************************************************/
  465.  
  466. static char *
  467. NextLabel (char *PrevLabel, void *Parameters)
  468.  
  469. {
  470.   struct FormatParameters *Params;
  471.   struct IncludeItemNode *IncludeItemNode;
  472.  
  473.   Params = Parameters;
  474.  
  475.   if (!PrevLabel)
  476.     {
  477.       AVL_InitTraversal (Params->Tree, &Params->StateInfo);
  478.     }
  479.   else
  480.     {
  481.       free (PrevLabel);
  482.     }
  483.  
  484.   while ((IncludeItemNode=(struct IncludeItemNode *)AVL_InOrder(&Params->StateInfo)))
  485.     {
  486.       for (Params->IncludeItemNodeNode=IncludeItemNode->Entries;
  487.        Params->IncludeItemNodeNode && Params->IncludeItemNodeNode->IncludeFileNode!=Params->IncludeFileNode;
  488.        Params->IncludeItemNodeNode=Params->IncludeItemNodeNode->Next)
  489.     ;
  490.       if (Params->IncludeItemNodeNode)
  491.     {
  492.       char *Label, *t;
  493.  
  494.       Label=xmalloc(strlen(IncludeItemNode->AnyNode.Name)+3);
  495.       t=stpcpy(Label,IncludeItemNode->AnyNode.Name);
  496.       if (IncludeItemNode->Function)
  497.         {
  498.           stpcpy(t,"()");
  499.         }
  500.       return Label;
  501.     }
  502.     }
  503.   return NULL;
  504. }
  505.  
  506. /************************************************************************/
  507. /*                                                                      */
  508. /* Print the link information                                           */
  509. /*                                                                      */
  510. /************************************************************************/
  511.  
  512. static void 
  513. PrintLink (void *Parameters)
  514.  
  515. {
  516.   struct IncludeItemNodeNode *IncludeItemNodeNode;
  517.  
  518.   IncludeItemNodeNode = ((struct FormatParameters *) Parameters)->IncludeItemNodeNode;
  519.   WPrintf ("\x22%s/File\x22 %lu",
  520.        IncludeItemNodeNode->IncludeFileNode->LinkName,
  521.        IncludeItemNodeNode->Line);
  522. }
  523.  
  524. /************************************************************************/
  525. /*                                                                      */
  526. /* Output the table of contents                                         */
  527. /*                                                                      */
  528. /************************************************************************/
  529.  
  530. static void 
  531. WriteTOC (struct IncludeFileNode *IncludeFileNode)
  532.  
  533. {
  534.   int i;
  535.  
  536.   WPrintf ("\n@NODE MAIN \x22%s\x22\n", IncludeFileNode->AnyNode.Name);
  537.   if (GlobalTOCFilename)
  538.     {
  539.       WPrintf("@TOC \x22%s/MAIN\x22\n",GlobalTOCFilename);
  540.     }
  541.   WPrintf ("\n@{\x22%s\x22 LINK File}\n", IncludeFileNode->AnyNode.Name);
  542.  
  543.   for (i=0; i<4; i++)
  544.     {
  545.       static struct
  546.     {
  547.       char *Header;
  548.       struct AVLTree *Tree;
  549.     } TOCParagraph[4]=
  550.       {
  551.         {"Structures",&StructureTree},
  552.         {"Unions",&UnionTree},
  553.         {"Typedefs",&TypedefTree},
  554.         {"#defines",&DefinesTree}
  555.       };
  556.  
  557.       struct FormatParameters FormatParameters;
  558.       char *Label;
  559.  
  560.       FormatParameters.IncludeFileNode = IncludeFileNode;
  561.       FormatParameters.Tree=TOCParagraph[i].Tree;
  562.       if ((Label=NextLabel(NULL,&FormatParameters)))
  563.     {
  564.       int *ColWidth;
  565.  
  566.       free (Label);
  567.       ColWidth = FormatNode (NextLabel, &FormatParameters);
  568.       WPrintf (*Arguments.Version >= 39 ? "\n\n@{b}%s@{ub}\n\n" : "\n\n%s\n\n", TOCParagraph[i].Header);
  569.       PrintNode (NextLabel, PrintLink, &FormatParameters, ColWidth);
  570.       free (ColWidth);
  571.     }
  572.     }
  573.   WPrintf ("\n@ENDNODE\n");
  574. }
  575.  
  576. /************************************************************************/
  577. /*                                                                      */
  578. /* Process a single include file.                                       */
  579. /*                                                                      */
  580. /************************************************************************/
  581.  
  582. static void
  583. ProcessIncludeFile (struct IncludeFileNode *CurrentIncludeFile)
  584.  
  585. {
  586.   struct Word *Word;
  587.   struct Word *TypedefWord, *TypedefName;
  588.   ULONG DefineCount;
  589.  
  590.   DefineCount = 0;
  591.  
  592.   ROpen (INCLUDEDIR, CurrentIncludeFile->AnyNode.Name);
  593.   WOpen (HYPERINCLUDEDIR, CurrentIncludeFile->AnyNode.Name);
  594.  
  595.   if (!Pass2)
  596.     {
  597.       CurrentIncludeFile->LinkName =
  598.     Arguments.FullPath ? xstrdup (WriteFilename) : CurrentIncludeFile->AnyNode.Name;
  599.     }
  600.  
  601.   WriteHeader (CurrentIncludeFile->LinkName, ReadFilename);
  602.  
  603.   if (Pass2)
  604.     {
  605.       WriteTOC (CurrentIncludeFile);
  606.     }
  607.  
  608.   TypedefWord = TypedefName = NULL;
  609.  
  610.   WPrintf ("@NODE File \x22%s\x22\n", CurrentIncludeFile->AnyNode.Name);
  611.   Word = ReadToken (FALSE, CurrentIncludeFile);
  612.   while (Word->Length)
  613.     {
  614.       if (Word->Length == 1 && Word->Special)
  615.     {
  616.       /* one character special "words" */
  617.       if (Word->Word[0] == '#')
  618.         {
  619.           /* Found a preprocessor command */
  620.  
  621.           WriteWord (Word);
  622.           FreeWord (Word);
  623.           Word = ReadWord (FALSE);
  624.           WriteWord (Word);
  625.           if (!strcmp (Word->Word, "include"))
  626.         {
  627.           /* #include */
  628.           FreeWord (Word);
  629.           Word = ReadWord (FALSE);
  630.           if (Pass2)
  631.             {
  632.               if (Word->Word[0] == '"' || Word->Word[0] == '<')
  633.             {
  634.               char *Filename;
  635.               struct IncludeFileNode *IncludeFileNode;
  636.  
  637.               WriteWord (Word);
  638.               Filename = ReadUntil (Word->Word[0] == '"' ? "\x22" : ">");
  639.               FreeWord (Word);
  640.               Word = ReadWord (FALSE);
  641.               if ((IncludeFileNode = (struct IncludeFileNode *) SearchNode (&IncludeFileTree, Filename)))
  642.                 {
  643.                   WPrintf ("@{\x22%s", Filename);
  644.                   WriteWhitespace (Word);
  645.                   WPrintf ("\x22 LINK \x22%s/File\x22}", IncludeFileNode->LinkName);
  646.                 }
  647.               else
  648.                 {
  649.                   WPrintf ("%s", Filename);
  650.                 }
  651.               WriteWord (Word);
  652.               FreeWord (Word);
  653.               Word = ReadWord (TRUE);
  654.               free (Filename);
  655.             }
  656.               else
  657.             {
  658.               fprintf (stderr, "%s, line %lu;\nError: Illegal #include syntax\n",
  659.                    ReadFilename, Word->Line);
  660.  
  661.               SetRC (RETURN_ERROR);
  662.             }
  663.             }
  664.           while (!Word->Newline)
  665.             {
  666.               WriteWord (Word);
  667.               FreeWord (Word);
  668.               Word = ReadWord (FALSE);
  669.             }
  670.         }
  671.           else if (!strcmp (Word->Word, "define") && DefineCount++)
  672.         {
  673.           /* #define */
  674.           FreeWord (Word);
  675.           Word = ReadWord (FALSE);
  676.           if (!Pass2)
  677.             {
  678.               struct IncludeItemNodeNode *IncludeItemNodeNode;
  679.               struct Word *NextWord;
  680.  
  681.               IncludeItemNodeNode = CreateIncludeItem (Word->Word,
  682.                                    &DefinesTree,
  683.                                    CurrentIncludeFile,
  684.                                    Word->Line);
  685.               NextWord = ReadWord (FALSE);
  686.               IncludeItemNodeNode->IncludeItemNode->Function =
  687.             (!NextWord->Whitespace && !NextWord->Newline && NextWord->Word[0] == '(');
  688.               UnreadWord (NextWord);
  689.             }
  690.           else
  691.             {
  692.               DoCurrentItem(CurrentIncludeFile, Word->Line, Word, &DefinesTree, TRUE);
  693.             }
  694.           FreeWord (Word);
  695.           Word = ReadWord (TRUE);
  696.         }
  697.           else
  698.         {
  699.           /* Unknown preprocessor command */
  700.           FreeWord (Word);
  701.           Word = ReadWord (TRUE);
  702.           while (Word->Length && !Word->Newline)
  703.             {
  704.               WriteWord (Word);
  705.               FreeWord (Word);
  706.               Word = ReadWord (TRUE);
  707.             }
  708.         }
  709.         }
  710.       else if (Word->Word[0] == ';')
  711.         {
  712.           if (TypedefWord)
  713.         {
  714.           if (TypedefName)
  715.             {
  716.               if (!Pass2)
  717.             {
  718.               CreateIncludeItem(TypedefName->Word,&TypedefTree,CurrentIncludeFile,TypedefWord->Line);
  719.             }
  720.               FreeWord (TypedefName);
  721.               TypedefName=NULL;
  722.             }
  723.           FreeWord (TypedefWord);
  724.           TypedefWord=NULL;
  725.         }
  726.           WriteWord (Word);
  727.           FreeWord (Word);
  728.           Word = ReadWord (TRUE);
  729.         }
  730.       else
  731.         {
  732.           WriteWord (Word);
  733.           FreeWord (Word);
  734.           Word = ReadWord (TRUE);
  735.         }
  736.     }
  737.       else if (!strcmp (Word->Word, "struct") ||
  738.            !strcmp (Word->Word, "union"))
  739.     {
  740.       UnreadWord (Word);
  741.       TypedefName = StructUnion (CurrentIncludeFile);
  742.       if (!TypedefWord)
  743.         {
  744.           FreeWord (TypedefName);
  745.           TypedefName=NULL;
  746.         }
  747.       Word = ReadWord (TRUE);
  748.     }
  749.       else if (!strcmp (Word->Word, "typedef"))
  750.     {
  751.       WriteWord (Word);
  752.       TypedefWord = Word;
  753.       TypedefName = NULL;
  754.       Word = ReadWord (FALSE);
  755.     }
  756.       else
  757.     {
  758.       if (TypedefWord)
  759.         {
  760.           struct Word *NextWord;
  761.  
  762.           NextWord = ReadToken (FALSE, CurrentIncludeFile);
  763.           if (NextWord->Word[0] == ')' || NextWord->Word[0]==';')
  764.         {
  765.           TypedefName = Word;
  766.           if (!DoCurrentItem(CurrentIncludeFile, TypedefWord->Line, Word, &TypedefTree, FALSE))
  767.             {
  768.               WriteWord (Word);
  769.             }
  770.         }
  771.           else
  772.         {
  773.           WriteIdentifier (Word, CurrentIncludeFile);
  774.           FreeWord (Word);
  775.         }
  776.           UnreadWord (NextWord);
  777.         }
  778.       else
  779.         {
  780.           WriteIdentifier (Word, CurrentIncludeFile);
  781.           FreeWord (Word);
  782.         }
  783.       Word = ReadWord (TRUE);
  784.     }
  785.       UnreadWord (Word);
  786.       Word = ReadToken (TRUE, CurrentIncludeFile);
  787.     }
  788.   FreeWord (Word);
  789.   WPrintf ("\n@ENDNODE\n");
  790.   WClose ();
  791.   RClose ();
  792. }
  793.  
  794. /************************************************************************/
  795. /*                                                                      */
  796. /* Process a single include file, first pass.                           */
  797. /*                                                                      */
  798. /************************************************************************/
  799.  
  800. void
  801. ProcessIncludeFile1 (char *Filename)
  802.  
  803. {
  804.   struct IncludeFileNode *IncludeFileNode;
  805.  
  806.   IncludeFileNode = (struct IncludeFileNode *) CreateNode (Filename, sizeof (struct IncludeFileNode));
  807.   AVL_InsertNode (&IncludeFileTree, (struct AVLNode *) IncludeFileNode);
  808.   ProcessIncludeFile (IncludeFileNode);
  809. }
  810.  
  811. /************************************************************************/
  812. /*                                                                      */
  813. /* Process a single include file, second pass.                          */
  814. /*                                                                      */
  815. /************************************************************************/
  816.  
  817. void
  818. ProcessIncludeFile2 (struct IncludeFileNode *IncludeFileNode)
  819.  
  820. {
  821.   printf ("Converting %s\n", IncludeFileNode->AnyNode.Name);
  822.   ProcessIncludeFile (IncludeFileNode);
  823. }
  824.